home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / datatypes / aiff / source / libcode.c < prev    next >
C/C++ Source or Header  |  1978-06-29  |  8KB  |  397 lines

  1. /*
  2. **    AIFF DataType
  3. **
  4. **    Written by Olaf `Olsen' Barthel <olsen@sourcery.han.de>
  5. **        Public domain
  6. **
  7. ** :ts=4
  8. */
  9.  
  10. #include "Data.h"
  11.  
  12.     // Mandatory library routines
  13.  
  14. struct ClassBase * __asm __saveds    LibInit(register __a0 BPTR LibSegment,register __d0 struct ClassBase *ClassBase,register __a6 struct ExecBase *ExecBase);
  15. struct ClassBase * __asm __saveds    LibOpen(register __a6 struct ClassBase *Base);
  16. BPTR __asm __saveds                    LibExpunge(register __a6 struct ClassBase *Base);
  17. BPTR __asm __saveds                    LibClose(register __a6 struct ClassBase *Base);
  18. LONG __asm __saveds                    LibNull(register __a6 struct ClassBase *Base);
  19.  
  20.     // The only user-callable routine
  21.  
  22. Class * __asm __saveds                GetClassEngine(register __a6 struct ClassBase *ClassBase);
  23.  
  24.     // Library header data, defined in "RomTag.asm"
  25.  
  26. extern UWORD __far    LibVersion,
  27.                     LibRevision;
  28. extern UBYTE __far    LibName[],
  29.                     LibID[];
  30.  
  31.     // Vector initialization table
  32.  
  33. APTR LibVectors[] =
  34. {
  35.     LibOpen,
  36.     LibClose,
  37.     LibExpunge,
  38.     LibNull,
  39.  
  40.     GetClassEngine,
  41.  
  42.     (APTR)-1
  43. };
  44.  
  45.     // Library initialization table for MakeLibrary()
  46.  
  47. struct { ULONG DataSize; APTR Table; APTR Data; struct ClassBase * (*Init)(); } __aligned LibInitTab =
  48. {
  49.     sizeof(struct ClassBase),
  50.     LibVectors,
  51.     NULL,
  52.     LibInit
  53. };
  54.  
  55.     /* AsyncStreamHandler():
  56.      *
  57.      *    A special stream handler for use with iffparse.library and the
  58.      *    asyncio routines.
  59.      */
  60.  
  61. STATIC LONG __saveds __asm
  62. AsyncStreamHandler(register __a0 struct Hook *Hook,register __a2 struct IFFHandle *Handle,register __a1 struct IFFStreamCmd *ActionPkt)
  63. {
  64.     struct AsyncFile    *Stream        = (struct AsyncFile *)Handle -> iff_Stream;
  65.     LONG                 Bytes        = ActionPkt -> sc_NBytes;
  66.  
  67.     switch(ActionPkt -> sc_Command)
  68.     {
  69.         case IFFCMD_READ:
  70.  
  71.             return(ReadAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
  72.  
  73.         case IFFCMD_WRITE:
  74.  
  75.             return(WriteAsync(Stream,ActionPkt -> sc_Buf,Bytes) != Bytes);
  76.  
  77.         case IFFCMD_SEEK:
  78.  
  79.             return(SeekAsync(Stream,Bytes,MODE_CURRENT) == -1);
  80.  
  81.         default:
  82.  
  83.             return(0);
  84.     }
  85. }
  86.  
  87.     /* LibInit():
  88.      *
  89.      *    Initialize the library.
  90.      */
  91.  
  92. struct ClassBase * __asm __saveds
  93. LibInit(register __a0 BPTR LibSegment,register __d0 struct ClassBase *ClassBase,register __a6 struct ExecBase *ExecBase)
  94. {
  95.         // Set up the header data
  96.  
  97.     ClassBase -> LibNode . lib_Node . ln_Type    = NT_LIBRARY;
  98.     ClassBase -> LibNode . lib_Node . ln_Name    = LibName;
  99.     ClassBase -> LibNode . lib_Flags            = LIBF_CHANGED | LIBF_SUMUSED;
  100.     ClassBase -> LibNode . lib_Version            = LibVersion;
  101.     ClassBase -> LibNode . lib_Revision            = LibRevision;
  102.     ClassBase -> LibNode . lib_IdString            = LibID;
  103.  
  104.         // Remember the segment pointer
  105.  
  106.     Segment = LibSegment;
  107.  
  108.         // Remember the exec library base pointer
  109.  
  110.     SysBase = ExecBase;
  111.  
  112.         // Initialize the shared data access semaphore
  113.  
  114.     InitSemaphore(&LockSemaphore);
  115.  
  116.         // Now take care of the IFFHandle I/O hook.
  117.  
  118.     AsyncHook . h_Entry = (HOOKFUNC)AsyncStreamHandler;
  119.  
  120.     return(ClassBase);
  121. }
  122.  
  123.     /* LibOpen(register __a6 struct ClassBase *ClassBase):
  124.      *
  125.      *    Open the library, as called via OpenLibrary()
  126.      */
  127.  
  128. struct ClassBase * __asm __saveds
  129. LibOpen(register __a6 struct ClassBase *ClassBase)
  130. {
  131.         // Increment usage count
  132.  
  133.     ClassBase -> LibNode . lib_OpenCnt++;
  134.  
  135.         // Prevent delayed expunge
  136.  
  137.     ClassBase -> LibNode . lib_Flags &= ~LIBF_DELEXP;
  138.  
  139.         // Is this the first initialization?
  140.  
  141.     if(ClassBase -> LibNode . lib_OpenCnt == 1)
  142.     {
  143.             // We are going to modify data while in multitasking,
  144.             // so watch out
  145.  
  146.         ObtainSemaphore(&LockSemaphore);
  147.  
  148.             // Open libraries & classes
  149.  
  150.         if(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",39))
  151.         {
  152.             if(IntuitionBase = OpenLibrary("intuition.library",39))
  153.             {
  154.                 if(UtilityBase = OpenLibrary("utility.library",39))
  155.                 {
  156.                     if(IFFParseBase = OpenLibrary("iffparse.library",39))
  157.                     {
  158.                         if(DataTypesBase = OpenLibrary("datatypes.library",39))
  159.                         {
  160.                             if(SuperClassBase = OpenLibrary("datatypes/sound.datatype",39))
  161.                             {
  162.                                     // Create a new class
  163.  
  164.                                 if(SoundClass = MakeClass(ClassBase -> LibNode . lib_Node . ln_Name,SOUNDDTCLASS,NULL,NULL,NULL))
  165.                                 {
  166.                                     extern Object * __saveds __asm ClassDispatch(register __a0 Class *class,register __a2 Object *object,register __a1 Msg msg);
  167.  
  168.                                         // Link the class dispatcher into it
  169.                                         // and keep a pointer to the library
  170.                                         // base
  171.  
  172.                                     SoundClass -> cl_Dispatcher . h_Entry    = (HOOKFUNC)ClassDispatch;
  173.                                     SoundClass -> cl_UserData                = (ULONG)ClassBase;
  174.  
  175.                                         // Make the class publicly available
  176.  
  177.                                     AddClass(SoundClass);
  178.  
  179.                                         // Release the lock
  180.  
  181.                                     ReleaseSemaphore(&LockSemaphore);
  182.  
  183.                                         // Return the library base pointer
  184.  
  185.                                     return(ClassBase);
  186.                                 }
  187.  
  188.                                     // Clean up...
  189.  
  190.                                 CloseLibrary(SuperClassBase);
  191.  
  192.                                 SuperClassBase = NULL;
  193.                             }
  194.  
  195.                             CloseLibrary(DataTypesBase);
  196.  
  197.                             DataTypesBase = NULL;
  198.                         }
  199.  
  200.                         CloseLibrary(IFFParseBase);
  201.  
  202.                         IFFParseBase = NULL;
  203.                     }
  204.  
  205.                     CloseLibrary(UtilityBase);
  206.  
  207.                     UtilityBase = NULL;
  208.                 }
  209.  
  210.                 CloseLibrary(IntuitionBase);
  211.  
  212.                 IntuitionBase = NULL;
  213.             }
  214.  
  215.             CloseLibrary(DOSBase);
  216.  
  217.             DOSBase = NULL;
  218.         }
  219.  
  220.             // Release the lock
  221.  
  222.         ReleaseSemaphore(&LockSemaphore);
  223.  
  224.             // No success
  225.  
  226.         return(NULL);
  227.     }
  228.     else
  229.         return(ClassBase);
  230. }
  231.  
  232.     /* LibExpunge(register __a6 struct ClassBase *ClassBase):
  233.      *
  234.      *    Expunge the library, remove it from memory
  235.      */
  236.  
  237. BPTR __asm __saveds
  238. LibExpunge(register __a6 struct ClassBase *ClassBase)
  239. {
  240.         // No more callers have the library open?
  241.  
  242.     if(!ClassBase -> LibNode . lib_OpenCnt && Segment)
  243.     {
  244.             // Remember the segment pointer, so it can be unloaded
  245.  
  246.         BPTR TempSegment = Segment;
  247.  
  248.             // Remove the library from the public list
  249.  
  250.         Remove(ClassBase);
  251.  
  252.             // Free the vector table and the library data
  253.  
  254.         FreeMem((BYTE *)ClassBase - ClassBase -> LibNode . lib_NegSize,ClassBase -> LibNode . lib_NegSize + ClassBase -> LibNode . lib_PosSize);
  255.  
  256.             // Return the segment pointer
  257.  
  258.         return(TempSegment);
  259.     }
  260.     else
  261.     {
  262.             // Expunge it later
  263.  
  264.         ClassBase -> LibNode . lib_Flags |= LIBF_DELEXP;
  265.  
  266.             // Can't close yet...
  267.  
  268.         return(NULL);
  269.     }
  270. }
  271.  
  272.     /* LibClose(register __a6 struct ClassBase *ClassBase):
  273.      *
  274.      *    Close the library, as called by CloseLibrary()
  275.      */
  276.  
  277. BPTR __asm __saveds
  278. LibClose(register __a6 struct ClassBase *ClassBase)
  279. {
  280.         // Decrement usage count
  281.  
  282.     if(ClassBase -> LibNode . lib_OpenCnt)
  283.         ClassBase -> LibNode . lib_OpenCnt--;
  284.  
  285.         // No more users?
  286.  
  287.     if(!ClassBase -> LibNode . lib_OpenCnt && SysBase)
  288.     {
  289.             // We are going to modify shared data,
  290.             // so watch out
  291.  
  292.         ObtainSemaphore(&LockSemaphore);
  293.  
  294.             // Clean up...
  295.  
  296.         if(SoundClass)
  297.         {
  298.             RemoveClass(SoundClass);
  299.  
  300.             FreeClass(SoundClass);
  301.  
  302.             SoundClass = NULL;
  303.         }
  304.  
  305.         if(SuperClassBase)
  306.         {
  307.             CloseLibrary(SuperClassBase);
  308.  
  309.             SuperClassBase = NULL;
  310.         }
  311.  
  312.         if(DataTypesBase)
  313.         {
  314.             CloseLibrary(DataTypesBase);
  315.  
  316.             DataTypesBase = NULL;
  317.         }
  318.  
  319.         if(UtilityBase)
  320.         {
  321.             CloseLibrary(UtilityBase);
  322.  
  323.             UtilityBase = NULL;
  324.         }
  325.  
  326.         if(IFFParseBase)
  327.         {
  328.             CloseLibrary(IFFParseBase);
  329.  
  330.             IFFParseBase = NULL;
  331.         }
  332.  
  333.         if(IntuitionBase)
  334.         {
  335.             CloseLibrary(IntuitionBase);
  336.  
  337.             IntuitionBase = NULL;
  338.         }
  339.  
  340.         if(DOSBase)
  341.         {
  342.             CloseLibrary(DOSBase);
  343.  
  344.             DOSBase = NULL;
  345.         }
  346.  
  347.             // Release the lock
  348.  
  349.         ReleaseSemaphore(&LockSemaphore);
  350.  
  351.             // Can we remove ourselves?
  352.  
  353.         if(ClassBase -> LibNode . lib_Flags & LIBF_DELEXP)
  354.             return(LibExpunge(ClassBase));
  355.     }
  356.  
  357.     return(NULL);
  358. }
  359.  
  360.     /* LibNull(register __a6 struct ClassBase *ClassBase):
  361.      *
  362.      *    Mandatory dummy function
  363.      */
  364.  
  365. LONG __asm __saveds
  366. LibNull(register __a6 struct ClassBase *ClassBase)
  367. {
  368.     return(NULL);
  369. }
  370.  
  371.     /* GetClassEngine(register __a6 struct ClassBase *ClassBase):
  372.      *
  373.      *    Get access to the class this library implements.
  374.      */
  375.  
  376. Class * __asm __saveds
  377. GetClassEngine(register __a6 struct ClassBase *ClassBase)
  378. {
  379.     Class *class;
  380.  
  381.         // Access shared data
  382.  
  383.     ObtainSemaphore(&LockSemaphore);
  384.  
  385.         // Remember the class pointer
  386.  
  387.     class = SoundClass;
  388.  
  389.         // Release the lock
  390.  
  391.     ReleaseSemaphore(&LockSemaphore);
  392.  
  393.         // Return the pointer
  394.  
  395.     return(class);
  396. }
  397.